from keyboard_us import layout

#Note that this has only been tested on english keyboards in Windows (!)
def bind_keyevents(obj, fnCallback, bindAll=False):
	"""Bind all key events. Provide a callback function, which will be executed after a key is pressed. This function can return "break" to stop the event.  """
	
	def _onEvent(event, fnCallback=fnCallback):
		"""Wrap the return value and call the callback. (fnCallback passed in from outer scope)."""
		if event.keycode==16 or event.keycode==17 or event.keycode==0: #Do not trigger on Ctrl, Shift, or Alt key alone
			return
		
		mods = ''
		if event.state & 0x00000004: mods += 'Ctrl+'
		if event.state & 0x00020000: mods += 'Alt+'
		if event.state & 0x00000001: mods += 'Shift+'
		
		strKey = layout.get(event.keycode,'') #Instead of event.char, we use a table of values.
		if strKey=='': return #unrecognized key
		
		keypressed = mods + strKey
		res = fnCallback(keypressed)
		return res #If this function returned 'break', return 'break'
	
	if bindAll:
		obj.bind_all('<Key>', _onEvent)
		obj.bind_all('<Any-Alt-Key>',_onEvent)
		obj.bind_all('<Tab>', _onEvent)
		obj.bind_all('<Shift-Tab>', _onEvent)
	else:
		obj.bind('<Key>', _onEvent)
		obj.bind('<Any-Alt-Key>',_onEvent)
		obj.bind('<Tab>', _onEvent)
		obj.bind('<Shift-Tab>', _onEvent)
		

if __name__=='__main__':
	from Tkinter import *
	root = Tk()
	def callback(key):
		print key
		if key=='Z':
			print 'yay!'
			return 'break'
	f = Frame(root)
	f.pack()
	
	e = Text(f)
	e.pack()
	bind_keyevents(e, callback)
		
	#~ bindAllKeyEvents(f, callback)
	f.mainloop()